<?php

namespace app\admin\controller;

use app\admin\library\Auth;
use app\BaseController;
use app\common\libray\traits\Admin;
use app\common\libray\Tree;
use app\common\model\AuthRule;
use think\facade\Config;
use think\facade\Session;
use think\facade\View;

class Base extends BaseController
{

    /**
     * 无需登录的方法,同时也就不需要鉴权了
     * @var array
     */
    protected $noNeedLogin = [];

    /**
     * 无需鉴权的方法,但需要登录
     * @var array
     */
    protected $noNeedRight = [];

    /**
     * 权限实例
     * @var null
     */
    protected $auth = null;
    /**
     * 当前模型
     * @var null
     */
    protected $model = null;
    /**
     * 默认配置文件
     * @var array
     */
    protected $config = [];

    protected $middleware = [
        'AuthCheck'
    ];
    /**
     * 搜索字符串
     * @var string
     */
    protected $searchFields = 'id';
    /**
     * 是否关联查询
     * @var bool
     */
    protected $relationSearch = false;

    /**
     * 是否开启Validate验证
     */
    protected $modelValidate = false;

    /**
     * 是否开启模型场景验证
     */
    protected $modelSceneValidate = false;

    protected $multiFields = ['status'];

    protected $field = '*';

    use Admin;


    public function initialize()
    {
        parent::initialize();
        $this->request->noNeedLogin = $this->noNeedLogin;
        $this->request->noNeedRight = $this->noNeedRight;
        $this->auth = Auth::instance();
        //相关操作
        $controller = $this->request->controller();
        $action = $this->request->action();
        $app = app('http')->getName();
        $path = strtolower(str_replace('.', '/', $controller) . '/' . $action);
        //统一渲染
        $upload = Config::get('upload');
        $config = [
            'app_name'        => $app,
            'controller_name' => $controller,
            'action_name'     => strtolower($action),
            'js_name'         => 'backend/' . strtolower(str_replace('.', '/', $controller)),
            'module_url'      => rtrim(url('/' . $app, [], false), '/'),
            'version'         => '0.0.1',
            'upload'          => $upload
        ];
        $option = [
            'auth'       => $this->auth,
            'admin'      => Session::get('admin'),
            'controller' => $controller,
            'action'     => $action,
            'app'        => $app,
            'path'       => $path,
            'config'     => $config,
        ];
        View::assign($option);
        $menu = $this->getMenu();
        View::assign('menu', $menu);
    }

    protected function getMenu()
    {
        $userRule = $this->auth->getRuleList();
        $pinyin = new \Overtrue\Pinyin\Pinyin('Overtrue\Pinyin\MemoryFileDictLoader');
        $badgeList = $selected = $referer = [];
        $fixedPage = 'index';
        //所有的菜单
        $ruleList = AuthRule::where('status', '=', '1')
            ->where('is_menu', 1)
            // ->cache('__menu__')
            ->select()
            ->toArray();
        $indexRuleList = AuthRule::where('status', '1')
            ->where('is_menu', 0)
            ->where('name', 'like', '%/index')
            ->column('pid', 'name');

        //找到非0 的父级ID  可能存在多级的情况
        $pidArr = array_filter(array_unique(array_column($ruleList, 'pid')));
        //筛查用户是否有主页权限
        foreach ($ruleList as $k => &$v) {
            //不是该用户的权限 剃掉
            if (!in_array($v['name'], $userRule)) {
                unset($ruleList[$k]);
                continue;
            }
            $indexRuleName = $v['name'] . '/index';
            if (isset($indexRuleList[$indexRuleName]) && !in_array($indexRuleName, $userRule)) {
                unset($ruleList[$k]);
                continue;
            }
            $v['icon'] = $v['icon'] . ' fa-fw';
            $v['url'] = '/' . $indexRuleName;
            $v['py'] = $pinyin->abbr($v['title'], '');
            $v['pinyin'] = $pinyin->permalink($v['title'], '');
            $selected = $v['name'] == $fixedPage ? $v : $selected;
        }
        unset($v);
        $lastArr = array_diff($pidArr, array_filter(array_unique(array_column($ruleList, 'pid'))));
        foreach ($ruleList as $index => $item) {
            if (in_array($item['id'], $lastArr)) {
                unset($ruleList[$index]);
            }
        }
        $tree = Tree::instance()->init($ruleList);
        $menu = $nav = '';
        //构造菜单数据
        $select_id = $selected ? $selected['id'] : 0;
        $template = '<li class="nav-item @class"><a url="@url"  py="@py" pinyin="@pinyin" href="@url"><i class="@icon"></i>@title</a>@childlist</li>';
        $menu = Tree::instance()->getTreeMenu(
            0,
            $template,
            $select_id,
            '',
            'ul',
            'class="nav nav-subnav"'
        );
        return $menu;
    }

    protected function buildParams($searchfields = null, $relationSearch = null)
    {
        $searchfields = is_null($searchfields) ? $this->searchFields : $searchfields;
        $relationSearch = is_null($relationSearch) ? $this->relationSearch : $relationSearch;
        $search = $this->request->get("search", '');
        $sort = $this->request->get("sort", !empty($this->model) && $this->model->getPk() ? $this->model->getPk() : 'id');
        $order = $this->request->get("order", "DESC");
        $offset = $this->request->get("offset", 0);
        $limit = $this->request->get("limit", 0);
        $where = [];
        $tableName = '';
        if ($relationSearch) {
            if (!empty($this->model)) {
                $name = $this->model->getTable();
                $tableName = $name . '.';
            }
            $sortArr = explode(',', $sort);
            foreach ($sortArr as $index => & $item) {
                $item = stripos($item, ".") === false ? $tableName . trim($item) : $item;
            }
            unset($item);
            $sort = implode(',', $sortArr);
        }
        if ($search) {
            $searcharr = is_array($searchfields) ? $searchfields : explode(',', $searchfields);
            foreach ($searcharr as $k => &$v) {
                $v = stripos($v, ".") === false ? $tableName . $v : $v;
            }
            unset($v);
            $where[] = [implode("|", $searcharr), "LIKE", "%{$search}%"];
        }

        $where = function ($query) use ($where) {
            foreach ($where as $k => $v) {
                if (is_array($v)) {
                    call_user_func_array([$query, 'where'], $v);
                } else {
                    $query->where($v);
                }
            }
        };
        $field = $this->field;
        return [$where, $sort, $order, $offset, $limit, $field];
    }
}

//id算法
//declare (strict_types=1);
//
//namespace apps\share\libs;
//
//class IdToStr
//{
//    const x = 177451812;
//    const a = 8728348608;
//    const s = [11, 10, 3, 8, 4, 6];
//    const t = 'fZodR9XQDSUm21yCkr6zBqiveYah8bt4xsWpHnJE7jL5VG3guMTKNPAwcF';
//
//    /*
//    const r = [
//        'f' => 0,'Z' => 1,'o' => 2,'d' => 3,'R' => 4,'9' => 5,'X' => 6,'Q' => 7,'D' => 8,'S' => 9,'U' => 10,'m' => 11,'2' => 12,'1' => 13,'y' => 14,
//        'C' => 15,'k' => 16,'r' => 17,'6' => 18,'z' => 19,'B' => 20,'q' => 21,'i' => 22,'v' => 23,'e' => 24,'Y' => 25,'a' => 26,'h' => 27,'8' => 28,
//        'b' => 29,'t' => 30,'4' => 31,'x' => 32,'s' => 33,'W' => 34,'p' => 35,'H' => 36,'n' => 37,'J' => 38,'E' => 39,'7' => 40,'j' => 41,'L' => 42,
//        '5' => 43,'V' => 44,'G' => 45,'3' => 46,'g' => 47,'u' => 48,'M' => 49,'T' => 50,'K' => 51,'N' => 52,'P' => 53,'A' => 54,'w' => 55,'c' => 56,
//        'F' => 57,
//    ];*/
//
//    public static function encode(int $x): string
//    {
//        $x = ($x ^ self::x) + self::a;
//        $r = ['B', 'V', '1', ' ', ' ', '4', ' ', '1', ' ', '7', ' ', ' '];
//
//        for ($i = 0; $i < 6; $i++) {
//            $r[self::s[$i]] = self::t[floor($x / pow(58, $i)) % 58];
//        }
//
//        return implode('', $r);
//    }
//
//    public static function decode(string $x): int
//    {
//        $r = self::getTable();
//
//        $s = 0;
//        for ($i = 0; $i < 6; $i++) {
//            $s += $r[$x[self::s[$i]]] * pow(58, $i);
//        }
//
//        return ($s - self::a) ^ self::x;
//    }
//
//    public static function getTable(): array
//    {
//        $r = [];
//
//        for ($i = 0; $i < 58; $i++) {
//            $r[self::t[$i]] = $i;
//        }
//        return $r;
//    }
//}
